﻿using GDM.Hogar.Aplicacion.IoC.TiempoDeVida;
using GDM.Hogar.Managers;
using GDM.Hogar.Managers.Contratos;
using GDM.Hogar.Repositorios;
using GDM.Hogar.Repositorios.Contratos;
using GDM.Hogar.Repositorios.Soporte;
using Microsoft.Practices.Unity;
using System;

namespace GDM.Hogar.Aplicacion.IoC
{
    public sealed class ContenedorUnity : IContenedorIoC
    {
        #region Miembtros Privados

        private readonly IUnityContainer _contenedor;

        #endregion Miembtros Privados

        #region constructor

        public ContenedorUnity()
        {
            var contenedor = new UnityContainer();
            ConfigurarContenedorRaiz(contenedor);
            _contenedor = contenedor;
        }

        #endregion constructor

        #region Implementacion de IContenedorIoC

        public void RegistrarTipo(Type tipo)
        {
            _contenedor.RegisterType(tipo, new TransientLifetimeManager());
        }

        public TServicio Resolver<TServicio>()
        {
            return _contenedor.Resolve<TServicio>();
        }

        public object Resolver(Type tipo)
        {
            return _contenedor.Resolve(tipo, null);
        }

        #endregion Implementacion de IContenedorIoC

        #region Metodos Privados

        private static void ConfigurarContenedorRaiz(IUnityContainer contenedor)
        {
            RegistrarRepositorios(contenedor);
            RegistrarManagers(contenedor);
        }

        private static void RegistrarManagers(IUnityContainer contenedor)
        {
            contenedor.RegisterType<IDbManager, DbManager>(new TiempoVidaContextoEjecucionManager());
            RegistrarTipo<ILoginManager, LoginManager>(contenedor);
            RegistrarTipo<IUsuarioManager, UsuarioManager>(contenedor);
            RegistrarTipo<IHogarManager, HogarManager>(contenedor);
            RegistrarTipo<IPersonalCocinaManager, PersonalCocinaManager>(contenedor);
            RegistrarTipo<ITareaManager, TareaManager>(contenedor);
            RegistrarTipo<IRemitoManager, RemitoManager>(contenedor);
            RegistrarTipo<IBeneficioPrevisionalManager, BeneficioPrevisionalManager>(contenedor);
            RegistrarTipo<IParteDiarioComedorManager, ParteDiarioComedorManager>(contenedor);
            RegistrarTipo<IParteQuincenalPersonalManager, ParteQuincenalPersonalManager>(contenedor);
            RegistrarTipo<IAgenteManager, AgenteManager>(contenedor);
            RegistrarTipo<IPuestoManager, PuestoManager>(contenedor);
            RegistrarTipo<ICargoManager, CargoManager>(contenedor);
            RegistrarTipo<ITipoDocumentoManager, TipoDocumentoManager>(contenedor);
            RegistrarTipo<IObraSocialManager, ObraSocialManager>(contenedor);
            RegistrarTipo<IProveedorManager, ProveedorManager>(contenedor);
            RegistrarTipo<IServicioEmergenciaManager, ServicioEmergenciaManager>(contenedor);
            RegistrarTipo<IIntegranteManager, IntegranteManager>(contenedor);
            RegistrarTipo<IVinculoManager, VinculoManager>(contenedor);
            RegistrarTipo<IPersonaReferenciaManager, PersonaReferenciaManager>(contenedor);
            RegistrarTipo<IActividadManager, ActividadManager>(contenedor);
            RegistrarTipo<IAsisteComedorViandaDiasManager, AsisteComedorViandaDiasManager>(contenedor);
            RegistrarTipo<ICodigoAusentismoManager, CodigoAusentismoManager>(contenedor);
            RegistrarTipo<IInscripcionManager, InscripcionManager>(contenedor);
        }

        private static void RegistrarRepositorios(IUnityContainer contenedor)
        {
            RegistrarTipo<IUsuarioRepositorio, UsuarioRepositorio>(contenedor);
            RegistrarTipo<IHogarRepositorio, HogarRepositorio>(contenedor);
            RegistrarTipo<IPersonalCocinaRepositorio, PersonalCocinaRepositorio>(contenedor);
            RegistrarTipo<ITareaRepositorio, TareaRepositorio>(contenedor);
            RegistrarTipo<IRemitoRepositorio, RemitoRepositorio>(contenedor);
            RegistrarTipo<IBeneficioPrevisionalRepositorio, BeneficioPrevisionalRepositorio>(contenedor);
            RegistrarTipo<IParteDiarioComedorRepositorio, ParteDiarioComedorRepositorio>(contenedor);
            RegistrarTipo<IParteQuincenalPersonalRepositorio, ParteQuincenalPersonalRepositorio>(contenedor);
            RegistrarTipo<IAgenteRepositorio, AgenteRepositorio>(contenedor);
            RegistrarTipo<IPuestoRepositorio, PuestoRepositorio>(contenedor);
            RegistrarTipo<ICargoRepositorio, CargoRepositorio>(contenedor);
            RegistrarTipo<ITipoDocumentoRepositorio, TipoDocumentoRepositorio>(contenedor);
            RegistrarTipo<IObraSocialRepositorio, ObraSocialRepositorio>(contenedor);
            RegistrarTipo<IProveedorRepositorio, ProveedorRepositorio>(contenedor);
            RegistrarTipo<IServicioEmergenciaRepositorio, ServicioEmergenciaRepositorio>(contenedor);
            RegistrarTipo<IIntegranteRepositorio, IntegranteRepositorio>(contenedor);
            RegistrarTipo<IPersonaReferenciaRepositorio, PersonaReferenciaRepositorio>(contenedor);
            RegistrarTipo<IVinculoRepositorio, VinculoRepositorio>(contenedor);
            RegistrarTipo<IActividadRepositorio, ActividadRepositorio>(contenedor);
            RegistrarTipo<IAsisteComedorViandaDiasRepositorio, AsisteComedorViandaDiasRepositorio>(contenedor);
            RegistrarTipo<ICodigoAusentismoRepositorio, CodigoAusentismoRepositorio>(contenedor);
            RegistrarTipo<IInscripcionRepositorio, InscripcionRepositorio>(contenedor);
        }

        private static void RegistrarTipo<TFrom, TTo>(IUnityContainer contenedor) where TTo : TFrom
        {
            contenedor.RegisterType<TFrom, TTo>(new TransientLifetimeManager());
        }

        #endregion Metodos Privados
    }
}